package com.lgmshare.k3.map;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;

import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import android.text.TextUtils;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;


/**
 * @author: LGM
 * @description: TODO
 * @email: lgmshare@gmail.com
 * @QQ:994976626
 * @datetime: 2017/3/30
 */
public class MapLocationService extends Service {

    private static final String TAG = "MapLocationService";

    public static final String INTENT_ACTION_LOCATION_START = "intent_action_location_start";
    public static final String INTENT_ACTION_LOCATION_STOP = "intent_action_location_stop";
    public static final String INTENT_ACTION_LOCATION_REQUEST = "intent_action_location_request";

    public static final String INTENT_FILTER_LOCATION_SUCCESS = "INTENT_FILTER_LOCATION_SUCCESS";
    public static final String INTENT_FILTER_LOCATION_FAIL = "INTENT_FILTER_LOCATION_SUCCESS";

    //定位频率
    private int SPAN_INTERVAL = 30;

    //声明LocationClient类对象
    private LocationClient mLocationClient = null;
    //声明定位参数
    private LocationClientOption mLocationOption;
    //声明定位回调监听器
    private BDLocationListener mLocationListener = new BDLocationListener() {

        @Override
        public void onReceiveLocation(BDLocation location) {
            if (handleLocationResult(location)) {
                handleLocationSuccess(location);
            } else {
                handleLocationFail(location);
            }
        }
    };

    private BroadcastReceiver mLocationReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case INTENT_ACTION_LOCATION_START:
                    startLocation();
                    break;
                case INTENT_ACTION_LOCATION_STOP:
                    stopLocation();
                    break;
                case INTENT_ACTION_LOCATION_REQUEST:
                    requestLocation();
                    break;
                default:
                    break;
            }
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        startLocation();
        //注册广播
        IntentFilter filter = new IntentFilter();
        filter.addAction(INTENT_ACTION_LOCATION_START);
        filter.addAction(INTENT_ACTION_LOCATION_STOP);
        filter.addAction(INTENT_ACTION_LOCATION_REQUEST);
        registerReceiver(mLocationReceiver, filter);
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopLocation();
        //注销广播
        unregisterReceiver(mLocationReceiver);
    }

    /**
     * 定位结果
     *
     * @param bdLocation
     * @return true：成功 false：失败
     */
    private boolean handleLocationResult(BDLocation bdLocation) {
        if (bdLocation == null) {
            return false;
        }
        boolean result = true;
        switch (bdLocation.getLocType()) {
            case BDLocation.TypeNone:
            case BDLocation.TypeServerError:
            case BDLocation.TypeNetWorkException:
            case BDLocation.TypeOffLineLocationNetworkFail:
            case BDLocation.TypeCriteriaException:
            case BDLocation.TypeOffLineLocationFail:
                result = false;
                break;
            default:
                break;
        }
        return result;
    }

    /**
     * 定位成功
     *
     * @param location
     */
    private void handleLocationSuccess(BDLocation location) {
        setLocationSpan(location);
        MapAddress address = new MapAddress();
        address.setLatitude(location.getLatitude());
        address.setLongitude(location.getLongitude());
        address.setCoordinateType(MapAddress.CoordinateType.BAIDU_09);
        address.setLocationType(location.getLocType());
        if (location.getLocType() != BDLocation.TypeGpsLocation) {
            //网络定位，附带了地址信息
            address.setProvince(location.getProvince() == null ? "" : location.getProvince());
            address.setCity(location.getCity() == null ? "" : location.getCity());
            address.setCounty(location.getDistrict() == null ? "" : location.getDistrict());
            if (!TextUtils.isEmpty(location.getStreetNumber())) {
                address.setAddress(location.getStreet() + location.getStreetNumber());
            } else {
                address.setAddress(location.getStreet() == null ? "" : location.getStreet());
            }
            address.setAdditionaladdress(location.getAddrStr());
        } else {
            //GPS定位，启动经纬度地址解析
            address.setAddress(location.getAddrStr());
        }
        sendLocationSuccessBroadcast("定位成功", address);
    }

    /**
     * 定位失败
     *
     * @param location
     */
    private void handleLocationFail(BDLocation location) {
        setLocationSpan(location);
        sendLocationFailBroadcast("定位失败");
    }

    /**
     * 设置更改定位频率-降低耗能
     *
     * @param location
     */
    private void setLocationSpan(BDLocation location) {
        if (location == null) {
            return;
        }
        if (location.getSpeed() < 1) {//速度低，降低定位频率
            //设置定位间隔60s
            mLocationOption.setScanSpan(SPAN_INTERVAL * 1000 * 2);
            //给定位客户端对象设置定位参数
            mLocationClient.setLocOption(mLocationOption);
        } else if (location.getSpeed() > 10) {//速度高，提高频率
            //设置定位间隔5s
            mLocationOption.setScanSpan((SPAN_INTERVAL / 6) * 1000);
            //给定位客户端对象设置定位参数
            mLocationClient.setLocOption(mLocationOption);
        } else {//恢复频率
            //设置定位间隔30s
            mLocationOption.setScanSpan(SPAN_INTERVAL * 1000);
            //给定位客户端对象设置定位参数
            mLocationClient.setLocOption(mLocationOption);
        }
    }

    /**
     * 开始定位
     */
    private void startLocation() {
        if (mLocationClient == null) {
            mLocationClient = new LocationClient(getApplicationContext());
            mLocationOption = new LocationClientOption();
            //设置定位模式为高精度模式，Battery_Saving为低功耗模式，Device_Sensors是仅设备模式
            mLocationOption.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系
            mLocationOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
            //设置是否返回地址信息（默认返回地址信息）
            mLocationOption.setIsNeedAddress(true);
            mLocationOption.setProdName("");
            mLocationOption.setOpenGps(true);//可选，默认false,设置是否使用gps
            //设置是否只定位一次,默认为false
            //mLocationOption.setOnceLocation(true);
            //设置是否强制刷新WIFI，默认为强制刷新
            //mLocationOption.setWifiActiveScan(true);
            //设置是否允许模拟位置,默认为false，不允许模拟位置
            //mLocationOption.setMockEnable(false);
            //设置定位间隔,单位毫秒,默认为2000ms
            mLocationOption.setScanSpan(SPAN_INTERVAL * 1000);
            //给定位客户端对象设置定位参数
            mLocationClient.setLocOption(mLocationOption);
            //设置定位回调监听
            mLocationClient.registerLocationListener(mLocationListener);
            //启动定位
        }
        mLocationClient.start();
    }

    /**
     * 停止定位
     */
    private void stopLocation() {
        if (mLocationClient != null) {
            mLocationClient.stop();
            mLocationClient = null;
        }
    }

    /**
     * 请求定位
     */
    private void requestLocation() {
        if (mLocationClient == null) {
            startLocation();
        } else {
            mLocationClient.requestLocation();
        }
    }

    /**
     * 发送定位广播-定位成功
     *
     * @param message
     * @param address
     */
    private void sendLocationSuccessBroadcast(String message, MapAddress address) {
        Intent intent = new Intent(INTENT_FILTER_LOCATION_SUCCESS);
        intent.putExtra("address", address);
        intent.putExtra("message", message);
        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
    }

    /**
     * 发送定位广播-定位失败
     *
     * @param message
     */
    private void sendLocationFailBroadcast(String message) {
        Intent intent = new Intent(INTENT_FILTER_LOCATION_FAIL);
        intent.putExtra("message", message);
        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
    }
}
